
/**************************************************************************/
/*     bitmap_import.cpp      CHAOXED's Bitmap Importing Dialog (Win32)   */
/*                            By: Josh Fiorio                             */
/**************************************************************************/

#include "bitmap_import.h"

//Global variables
extern FrameBuffer fbuf;                    //to write our pixels to
extern int mousex, mousey, mousedown;       //to move our mouse
extern palette palettes[17];                //to write our colors to
extern int pl1Sel;                          //to determine which colors to use

//Bitmap Import Dialog Variables
char *bi_filename=(char*)malloc(MAX_PATH);
bool cipo=false;
bool dren=false;
bool cip=false;
bool bl=true;
int scrx=0;
int scry=0;
int scrm=2;
int ciw=0;
int cih=0;
int rectt, rectb, rectl, rectr;
BITMAPINFO bi; 
HBITMAP it=NULL;
BYTE *nbts;

BOOL CALLBACK BI_DLG_Func(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
	switch (message)
	{
	case WM_PAINT:
		{
			//declare vars
			HWND box=GetDlgItem(hwnd, IDC_PORTIONBOX);
			HDC hDC, mhDC;
			PAINTSTRUCT Ps;
			Ps.fErase = false;

			//Begin painting
			hDC = BeginPaint(box, &Ps);
			RECT selRect; selRect.bottom=rectb; selRect.left=rectl; selRect.right=rectr; selRect.top=rectt;
			
			//New buffer
			mhDC = CreateCompatibleDC(hDC);
			SelectObject(mhDC, it);
			FrameRect(mhDC, &selRect, CreateSolidBrush(RGB(255,255,255)));
			StretchBlt(mhDC,0,0,270*scrm,212*scrm,mhDC,scrx,scry,270,212,SRCCOPY);
			BitBlt(hDC, 0,0, 270, 212, mhDC, 0, 0, SRCCOPY);

			//Delete buffer; we don't need it anymore
			DeleteDC(mhDC);
			
			// Restore the old pixels in our bitmap
			SetDIBits(hDC, it, 0, bi.bmiHeader.biHeight, nbts, &bi, DIB_RGB_COLORS);
			EndPaint(box, &Ps);
		}
		return false;
	case WM_INITDIALOG:
		SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM) LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(MAIN_ICON)));
		cip=false;
		cipo=false;
		return true;
		break;
	case WM_CLOSE:
		DeleteObject(it);
		EndDialog(hwnd, 0);
		break;
	case WM_COMMAND:
		if (LOWORD(wparam) == IDC_BROWSE)
		{
			//Browse for file
			char *bname;
			if (!(bname = OpenFileBox(
				"Import a Bitmap File",
				"Bitmap Files\0*.bmp\0All Files\0*.*\0"
				))) { return 0; }

			//Copy pointed data into an array
			int len=0;
			bool done=false;
			while (!done)
			{
				bi_filename[len] = *(bname+len);
				if (*(bi_filename + len) == 0)
					done=true;
				len++;
			}	//end copying

			//Load bitmap
			it = (HBITMAP)LoadImage(GetModuleHandle(NULL), bi_filename, IMAGE_BITMAP, 0, 0,
				LR_LOADFROMFILE);
			
			//Get bitmap info
			BITMAP bminfo;
			GetObject(it, sizeof(bminfo), &bminfo);
			ciw=bminfo.bmWidth; cih=bminfo.bmHeight;

			//Begin painting
			PAINTSTRUCT Ps;
			Ps.fErase = false;
			HDC hDC = BeginPaint(GetDlgItem(hwnd, IDC_PORTIONBOX), &Ps);

			//Make image size of buffer, if not bigger already
			if (ciw < 272 || cih < 214)
			{
				//Pixels to read
				BYTE *bbts=(BYTE *)malloc(cih*ciw*(bminfo.bmBitsPixel/8));
				nbts=(BYTE *)malloc(272*214*(bminfo.bmBitsPixel/8));
				memset(nbts,200,272*214*(bminfo.bmBitsPixel/8));
				BYTE b,g,r;

				//When reading pixels, we need to give the func info on the bitmap
				memset(&bi,0,sizeof(BITMAPINFO)); 
				bi.bmiHeader.biSize      = sizeof(BITMAPINFOHEADER); 
				bi.bmiHeader.biWidth    = ciw; 
				bi.bmiHeader.biHeight    = cih; 
				bi.bmiHeader.biPlanes    = 1; 
				bi.bmiHeader.biBitCount    = bminfo.bmBitsPixel; 
				bi.bmiHeader.biCompression  = BI_RGB; 
				bi.bmiHeader.biSizeImage  = ciw*cih*bminfo.bmBitsPixel/8;  
				GetDIBits(hDC, it, 0, cih, bbts, &bi, DIB_RGB_COLORS);

				//Set bytes
				for (int y=0; y<cih; y++)
				{
					for (int x=0; x<ciw; x++)
					{
						b=*(bbts+((bminfo.bmBitsPixel/8)*(x+(cih-1-y)*ciw)+0));
						g=*(bbts+((bminfo.bmBitsPixel/8)*(x+(cih-1-y)*ciw)+1)); 
						r=*(bbts+((bminfo.bmBitsPixel/8)*(x+(cih-1-y)*ciw)+2)); 

						nbts[(bminfo.bmBitsPixel/8)*(x+(214-1-y)*272)+0] = b; 
						nbts[(bminfo.bmBitsPixel/8)*(x+(214-1-y)*272)+1] = g; 
						nbts[(bminfo.bmBitsPixel/8)*(x+(214-1-y)*272)+2] = r;
					}	//end for
				}	//end for

				//Set new info for setting bytes
				bi.bmiHeader.biWidth=272;
				bi.bmiHeader.biHeight=214;
				bi.bmiHeader.biSizeImage=272*214*bminfo.bmBitsPixel/8;
				it = CreateCompatibleBitmap(hDC, 272, 214);
				SetDIBits(hDC, it, 0, 272, nbts, &bi, DIB_RGB_COLORS);
			}
			else
			{
				//declare the array to hold the new pixels
				nbts=(BYTE *)malloc(ciw*cih*(bminfo.bmBitsPixel/8));
				
				//Read the pixels into our buffer
				memset(&bi,0,sizeof(BITMAPINFO)); 
				bi.bmiHeader.biSize      = sizeof(BITMAPINFOHEADER); 
				bi.bmiHeader.biWidth    = ciw; 
				bi.bmiHeader.biHeight    = cih; 
				bi.bmiHeader.biPlanes    = 1; 
				bi.bmiHeader.biBitCount    = bminfo.bmBitsPixel; 
				bi.bmiHeader.biCompression  = BI_RGB; 
				bi.bmiHeader.biSizeImage  = ciw*cih*bminfo.bmBitsPixel/8;  
				GetDIBits(hDC, it, 0, cih, nbts, &bi, DIB_RGB_COLORS);
			}	//end if
			EndPaint(GetDlgItem(hwnd, IDC_PORTIONBOX), &Ps);
	
			//Set text of control to filename
			bl=true;
			SetDlgItemText(hwnd, IDC_FILEPATH, bi_filename);
		}	//end if

		if (LOWORD(wparam) == IDC_CIP)
		{
			//Simulate a check
			if (cip == false)
				cip = true;
			else
				cip = false;
			//end if
		}	//end if

		if (LOWORD(wparam) == IDC_CIPO)
		{
			//Simulate a check
			if (cipo == false)
				cipo = true;
			else
				cipo = false;
			//end if
		}	//end if

		if (LOWORD(wparam) == IDOK)
		{
			//declare rect to store our selected portion pos's in so we can send it to certain functions
			fbuf.Clear();
			if (cip)
			{
				if (!cipo) {rectb =-20;}	//this way we tell it we haven't selected anything
					BitmapToBuf(bi_filename, fbuf, palettes[pl1Sel], BI_PRIORITY, rectt, rectl, rectb, rectr);
				if (MessageBox(hwnd, "Write palette to actual ROM?", "Question", MB_ICONQUESTION | MB_YESNO) == IDYES)
					WritePalette(palettes[pl1Sel]);
				//end if
			}	//end if
			else
				if (!cipo) {rectb =-20;}	//this way we tell it we haven't selected anything
				BitmapToBuf(bi_filename, fbuf, palettes[pl1Sel], BI_NO_IMPORT, rectt, rectl, rectb, rectr);
			//end if

			EndDialog(hwnd, 0);
		}	//end if
		
		if (LOWORD(wparam)==DEMAG_BM)
		{
			if (scrm > 1) {scrm--;}
			if (!(scrx < (ciw-(272/scrm)))) {if (ciw-(272/scrm) > 0) {scrx = (ciw-(272/scrm));}}
			if (!(scrx > 0)) {scrx = 0;}
			if (!(scry < (cih-(212/scrm)))) {if (cih-(212/scrm) > 0) {scry = (cih-(212/scrm));}}
			if (!(scry > 0)) {scry = 0;}
		}	//end if

		if (LOWORD(wparam)==MAG_BM)
		{
			scrm++;
			if (!(scrx < (ciw-(272/scrm)))) {if (ciw-(272/scrm) > 0) {scrx = (ciw-(272/scrm));}}
			if (!(scrx > 0)) {scrx = 0;}
			if (!(scry < (cih-(212/scrm)))) {if (cih-(212/scrm) > 0) {scry = (cih-(212/scrm));}}
			if (!(scry > 0)) {scry = 0;}
		}	//end if

		if (LOWORD(wparam) == IDC_U)
		{
			if (scry > 0) {scry--;}
			else {scry=0;}
		}	//end if

		if (LOWORD(wparam) == IDC_D)
		{
			if (scry < (cih-(212/scrm))) {scry++;}
			else if (cih-(212/scrm) > 0) {scry = (cih-(212/scrm));}
		}	//end if

		if (LOWORD(wparam) == IDC_L)
		{
			if (scrx > 0) {scrx--;}
			else {scrx=0;}
		}	//end if

		if (LOWORD(wparam) == IDC_R)
		{
			if (scrx < (ciw-(272/scrm))) {scrx++;}
			else if (ciw-(272/scrm) > 0) {scrx = (ciw-(272/scrm));}
		}	//end if

		//Paint stuff
		InvalidateRect(hwnd, NULL, false);
		return true;
		break;
	case WM_LBUTTONDOWN:
		//set var. vals
		mousedown=true; if (cipo){
		rectt=0; rectb=0; rectl=0; rectr=0;
		
		//stuff for click our window
		POINT mousepnt;				//point for store mouse pos
		RECT windrect, contrect;	//point for store window & control pos

		//Get poses of stuff
		GetWindowRect(hwnd, &windrect);
		GetWindowRect(GetDlgItem(hwnd, IDC_PORTIONBOX), &contrect);
		GetCursorPos(&mousepnt);

		//Do math to figure relativatey to control
		mousex=((mousepnt.x-contrect.left))+(scrx*scrm);
		mousey=((mousepnt.y-contrect.top))+(scry*scrm);
		mousex = mousex - (mousex % (scrm));
		mousey = mousey - (mousey % (scrm));
		rectt = (mousey/scrm);
		rectl = (mousex/scrm);

		//Paint stuff
		InvalidateRect(hwnd, NULL, false);}
		break;
	case WM_LBUTTONUP:
		mousedown=false;
		break;
	case WM_MOUSEMOVE:
		//check if we are painting to our static picture
		if (mousedown && cipo)
		{
			//stuff for click our window
			POINT mousepnt;				//point for store mouse pos
			RECT windrect, contrect;	//point for store window & control pos

			//Get poses of stuff
			GetWindowRect(hwnd, &windrect);
			GetWindowRect(GetDlgItem(hwnd, IDC_PORTIONBOX), &contrect);
			GetCursorPos(&mousepnt);

			//Do math to figure relativatey to control
			mousex=((mousepnt.x-contrect.left))+(scrx*scrm)+(scrm);
			mousey=((mousepnt.y-contrect.top))+(scry*scrm)+(scrm);
			mousex = mousex - (mousex % (scrm));
			mousey = mousey - (mousey % (scrm));
			rectb = (mousey/scrm);
			rectr = (mousex/scrm);

			//Paint stuff
			InvalidateRect(hwnd, NULL, false);
		}	//end if
		break;


	default:
		return false;
	}	//end switch

	return true;
}	//end of func.
